#########################################################################
# File : /lua/system/config.lua
# Description : Sets up basic lua behavior
# Author : GPG / Neruz
#########################################################################

# Disable the LuaPlus bit where you can add attributes to nil, numbers, and strings.

local function metacleanup(obj)
    local name = type(obj)
    mmt = {
        __newindex = function(table,key,value)
            error(string.format("Attempt to set attribute '%s' on %s", tostring(key), name), 2)
        end,
        #__index = function(table,key)
        #    error(string.format("Attempt to get attribute '%s' on %s", tostring(key), name), 2)
        #end
    }
    setmetatable(getmetatable(obj), mmt)
end

metacleanup(nil)
metacleanup(0)
# commenting out the following code enables lua do s = '' s:func() and such,
# unfortunately '':func() is not a correct syntax
# use (''):func() instead
# metacleanup('')

# print( "%(key)s is %(val)7.2f%" % {key = "concentration", val = 56.2795} )
# function interp(s, tab)
#  return (s:gsub('%%%((%a%w*)%)([-0-9%.]*[cdeEfgGiouxXsq])',
#            function(k, fmt) return tab[k] and ("%"..fmt):format(tab[k]) or
#                '%('..k..')'..fmt end))
# end
# getmetatable("").__mod = interp

# Set up a metatable for coroutines (a.k.a. threads)

local thread_mt = {Destroy = KillThread}
thread_mt.__index = thread_mt
function thread_mt.__newindex(table,key,value)
    error('Attempt to set an attribute on a thread',2)
end
local function dummy() end
setmetatable(getmetatable(coroutine.create(dummy)),thread_mt)


# Replace math.random with our custom random.  On the sim side, this is
# a rng with consistent state across all clients.

if Random then
    math.random = Random
end


# Give globals an __index() with an error function. This causes an error message
# when a nonexistent global is accessed, instead of just quietly returning nil.

local globalsmeta = {
    __index = function(table, key)
        WARN(debug.traceback("access to nonexistent global variable "..repr(key)))
    end
}
setmetatable(_G, globalsmeta)

function GlobalExists(key)
    return rawget(_G,key) != nil
end

# Check if an item is callable, ie not a variable. Returns the callable item,
# otherwise returns nil

function iscallable(f)
    local tt = type(f)
    if tt == 'function' or tt == 'cfunction' then
        return f
    end
    if tt == 'table' and getmetatable(f).__call then
        return f
    end
end


